home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / castools.zip / ADDTOGRO.C < prev    next >
Text File  |  1990-02-15  |  6KB  |  232 lines

  1.  
  2.  
  3. /*
  4.    ADDTOGRO.C Function PbAddToGroup:  Adds a person entry to a group entry.
  5.  
  6.    INPUT:  Phonebook structure, and the record id's of the person and group
  7.       entries.
  8.  
  9.    OUTPUT: If successful, adds the person to the group's members list, and the
  10.       group to the person's members list.  If the new member changes the
  11.       group's HardwareType, that field is changed.
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <malloc.h>
  16. #include <phonebk.h>
  17.  
  18. int pascal PbAddToGroup(PB *pb, int GroupID, int MemberID)
  19. {
  20.   int retval = FAIL;        /* default, if anything goes wrong */
  21.   PBE *group = NULL,
  22.       *member = NULL;
  23.   LONGWORD group_offset,
  24.        member_offset;
  25.   int new_free_bytes;
  26.   int buffed_rids;
  27.  
  28.   int i,
  29.       writ,             /* for return value of fwrite() */
  30.       filenum;
  31.   int temperrno = 0;         /* for saving aside Pberrno */
  32.  
  33.   Pberrno = 0;                     /* Initially, always reset */
  34.  
  35.   /* First, check params */
  36.   if (pb == NULL) {
  37.     Pberrno = INVALIDPARAMETER;
  38.     return(NULL);
  39.   }
  40.   if ((GroupID < 0) ||
  41.       (GroupID > 999)) {
  42.     Pberrno = INVALIDPARAMETER;
  43.     return(NULL);
  44.   }
  45.   if ((MemberID < 0) ||
  46.       (MemberID > 999)) {
  47.     Pberrno = INVALIDPARAMETER;
  48.     return(NULL);
  49.   }
  50.  
  51.   /* First, fetch the entries */
  52.   if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
  53.     goto getout;      /* PbGetEntry sets Pberrno */
  54.   }
  55.   if (!(member = PbGetEntry(pb, NULL, NULL, MemberID))) {
  56.     goto getout;
  57.   }
  58.  
  59.   /* A few consistency checks */
  60.   if (member->type != PERSONENTRY) {
  61.     Pberrno = GROUPCANTBEMEMBER;
  62.     goto getout;
  63.   }
  64.  
  65.   if (group->type != GROUPENTRY) {
  66.     Pberrno = PERSONCANTHAVEMEMBER;
  67.     goto getout;
  68.   }
  69.  
  70.     /* Check that the group doesn't already have the person as a member */
  71.   for (i=0; i<group->members; i++) {
  72.     if (group->MemberList[i] == MemberID) {
  73.       break;
  74.     }
  75.   }
  76.   if (i != group->members) {
  77.     Pberrno = ENTRYALREADYMEMBER;
  78.     goto getout;
  79.   }
  80.  
  81.   /* Check that operation will not put phonebook's 'unused bytes' over limit */
  82.   if (new_free_bytes = (pb->header.FreeBytes +
  83.             group->length +
  84.             member->length) > MAXUNUSEDBYTES) {
  85.     Pberrno = TOOMANYFREEBYTES;
  86.     goto getout;
  87.   }
  88.  
  89.   /* Update fields of both entries */
  90.   group->MemberList = (int *)realloc(group->MemberList,
  91.                      (group->members + 1) * sizeof(int));
  92.   group->MemberList[group->members++] = MemberID;
  93.   group->length += sizeof(int);
  94.   member->MemberList = (int *)realloc(member->MemberList,
  95.                   (member->members + 1) * sizeof(int));
  96.   member->MemberList[member->members++] = GroupID;
  97.   member->length += sizeof(int);
  98.  
  99.   /* Set or change the hardware type of the group as appropriate */
  100.   if (group->members == 1) {          /* we're adding the first member */
  101.     group->HardwareType = member->HardwareType;
  102.   }
  103.   else if ((group->HardwareType == HASCCC) &&
  104.        (member->HardwareType == FAXONLY)) {
  105.     group->HardwareType = FAXONLY;
  106.   }
  107.  
  108.   /* Find out new offsets for the entries, in case the write is successful */
  109.   filenum = fileno(pb->fp);
  110.   if ((member_offset = filelength(filenum)) == -1L) {
  111.     Pberrno = FILELENGTHERROR;
  112.     goto getout;
  113.   }
  114.   group_offset = member_offset + member->length;
  115.  
  116.   /* Write the person entry to end of the file, quitting if error occurs */
  117.   if (fseek(pb->fp, 0L, SEEK_END)) {
  118.     Pberrno = FSEEKERROR;
  119.     goto getout;
  120.   }
  121.  
  122.   /* First, write the fixed part... */
  123.   writ = fwrite(member, sizeof(PBEFIXED), 1, pb->fp);
  124.   if (writ != 1) {
  125.     Pberrno = CANTWRITE;
  126.     goto getout;
  127.   }
  128.  
  129.   /* ... then each of the optional fields, INCLUDING their NULL terminator... */
  130.   for (i=0; i<pb->header.fields; i++) {
  131.     writ = fwrite(member->fields[i], strlen(member->fields[i]) + 1, 1, pb->fp);
  132.     if (writ != 1) {
  133.       Pberrno = CANTWRITE;
  134.       goto getout;
  135.     }
  136.   }
  137.  
  138.   /* ... and finally the membership list */
  139.   writ = fwrite(member->MemberList,
  140.         sizeof(int),
  141.         member->members,
  142.         pb->fp);
  143.   if (writ != member->members) {
  144.     Pberrno = CANTWRITE;
  145.     goto getout;
  146.   }
  147.  
  148.   /* And write the group, too:    first the fixed part, ... */
  149.   writ = fwrite(group, sizeof(PBEFIXED), 1, pb->fp);
  150.   if (writ != 1) {
  151.     Pberrno = CANTWRITE;
  152.     goto getout;
  153.   }
  154.  
  155.   /* ...then the membership list */
  156.   writ = fwrite(group->MemberList,
  157.         sizeof(int),
  158.         group->members,
  159.         pb->fp);
  160.   if (writ != group->members) {
  161.     Pberrno = CANTWRITE;
  162.     goto getout;
  163.   }
  164.  
  165.   /* If we got here, can update record ID's offsets and other pb fields*/
  166.  
  167.   /* If the Offset buffer is being used, check there for the id's */
  168.   if (pb->OBuffer) {
  169.     buffed_rids = pb->OBufferSize/sizeof(LONGWORD);
  170.  
  171.     /* If the id's are in the buffer, update them there */
  172.     if ((MemberID >= pb->FirstOBufferRID) &&
  173.     (MemberID < pb->FirstOBufferRID + buffed_rids)) {
  174.       pb->OBuffer[MemberID - pb->FirstOBufferRID] = member_offset;
  175.     }
  176.     if ((GroupID >= pb->FirstOBufferRID) &&
  177.     (GroupID < pb->FirstOBufferRID + buffed_rids)) {
  178.       pb->OBuffer[GroupID - pb->FirstOBufferRID] = group_offset;
  179.     }
  180.   }
  181.  
  182.   /* And finally do the actual writes to the file */
  183.   if (fseek(pb->fp, 160L + MemberID * sizeof(LONGWORD), SEEK_SET)) {
  184.     Pberrno = FSEEKERROR;
  185.     goto getout;
  186.   }
  187.   writ = fwrite(&member_offset, sizeof(LONGWORD), 1, pb->fp);
  188.   if (writ != 1) {
  189.     Pberrno = CANTWRITE;
  190.     goto getout;
  191.   }
  192.   if (fseek(pb->fp, 160L + GroupID * sizeof(LONGWORD), SEEK_SET)) {
  193.     Pberrno = FSEEKERROR;
  194.     goto getout;
  195.   }
  196.   writ = fwrite(&group_offset, sizeof(LONGWORD), 1, pb->fp);
  197.   if (writ != 1) {
  198.     Pberrno = CANTWRITE;
  199.     goto getout;
  200.   }
  201.  
  202.   /* And now set the FreeBytes phonebook field */
  203.   pb->header.FreeBytes = new_free_bytes;
  204.   if (fseek(pb->fp, 6L, SEEK_SET)) {
  205.     Pberrno = FSEEKERROR;
  206.     goto getout;
  207.   }
  208.   writ = fwrite(&pb->header.FreeBytes, sizeof(int), 1, pb->fp);
  209.   if (writ != 1) {
  210.     Pberrno = CANTWRITE;
  211.     goto getout;
  212.   }
  213.  
  214.   /* If we got all the way to here, all went well! */
  215.   retval = SUCCESS;
  216.  
  217. getout:
  218.   if (Pberrno) {
  219.     temperrno = Pberrno;
  220.   }
  221.   if (group) {
  222.     PbFreePBE(pb, group);
  223.   }
  224.   if (member) {
  225.     PbFreePBE(pb, member);
  226.   }
  227.   if (temperrno) {
  228.     Pberrno = temperrno;
  229.   }
  230.   return(retval);
  231. }
  232.